package edu.indiana.d2i.ontology;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

import edu.indiana.d2i.ontology.util.AccessDBUtil;
import edu.indiana.d2i.ontology.util.Constants;

import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;

/**
 * abstract class for every resource in the RDF graph, each resource 
 * represents one row in a corresponding table
 */
public abstract class AbstractSQLExec {
	protected AccessDBUtil dbCon = null;	// connector to the database
	protected OntModel model = null; 		// Jena model
	protected int id = -1;					// id for this resource in database 
	protected String subjectURI = null;		// URI for subject in this triple
	protected String sqlStatement = null;	// SQL statement used to fetch records 
	protected String nameSpace =			// name space of each resource
		"http://www.semanticweb.org/ontologies/2011/3/Ontology1303230739450.owl#";
	protected String resourceURI = null;	// an unique ID for this resource
	protected Individual individual = null; // an instance for a certain class
	protected Set<String> wordsEliminated 	// 
				= new HashSet<String>();
	
	
	/**
	 * Add all the data properties to this resource, here the resource is an subject.
	 * @param sql
	 */
	protected void addDataProperties(String sql) {
		assert resourceURI != null;
		
		try {
			ResultSet resultSet = dbCon.query(sql);
			if (resultSet.next()) {
				ResultSetMetaData metaData = resultSet.getMetaData();
				
				int colCount = metaData.getColumnCount();
				for (int i = 1; i <= colCount; i++) {
					String columnName = metaData.getColumnName(i);
					if (columnName.equals("ID") || columnName.startsWith("FK_")) continue;
					
					DatatypeProperty pHasValue = model.createDatatypeProperty(Constants.NAME_SPACE + "has_" + columnName);
					String tmp = resultSet.getString(columnName);
					if (tmp == null) tmp = "";
					model.add(individual, pHasValue, tmp);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * This method must be override by sub classes, it will build:
	 * subject <-- belongs_to -- resource -- has_component --> object
	 * So resource acts as object and subject.
	 * @param subjectURI
	 */
	protected abstract void addObjectProperties(String subjectURI);
	
	public AbstractSQLExec(AccessDBUtil dbCon, OntModel model, int id, String subjectURI) {
		this.dbCon = dbCon;
		this.model = model;
		this.id = id;
		this.subjectURI = subjectURI;
	}
	
	public String getResourceURI() {
		return resourceURI;
	}
	
	public Individual getIndividual() {
		return individual;
	}
	
	/**
	 * the method to dump data to the ontology model based on Jena API
	 */
	public void setData2JenaModel() {
		assert sqlStatement != null;
		
		// add data properties				
//		addDataProperties(sqlStatement);
		
		// add object properties
		addObjectProperties(subjectURI);
	}
	
	public Model getJenaModel() {
		return model;
	}
}
